package com.ping.controller;

import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import com.eaio.uuid.UUID;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.ping.model.Ping;
import com.ping.model.ResponseEnum;
import com.ping.model.Store;
import com.ping.model.User;
import com.ping.service.BaseService;

public class PingController extends BaseController{
	public static final String OPERATION = "operation";
	public static final String OPERATOR = "operator";
	
	public void add(){
		if (!checkQuery()) {
			return;
		}
		
		String query = getPara(QUERY_STATEMENT);
		String[] necessary = {Ping.MARKET, Ping.CAT, Ping.HAVE, 
				Ping.TARGET, Ping.PUBLISHER, Ping.STORE};
		
		BaseService service = new BaseService() {
			@Override
			public void genRecord(Record record, LinkedList<String> params,
					LinkedList<String> values) {
				// TODO Auto-generated method stub
				params.add(Ping.UUID);
				UUID uuid = new UUID();
				values.add(uuid.toString());
				
				params.add(Ping.T);
				values.add(String.valueOf(Calendar.getInstance().getTimeInMillis()));
				
				super.genRecord(record, params, values);
			}
		};
		
		if (!service.meet(query, necessary)) {
			renderLack();
			return;
		}
		
		if (service.add(Ping.TABLE_NAME, query)) {
			renderSuccess();
		}else {
			renderOperateError();
		}
	}
	
	public void info(){
		if (!checkQuery()) {
			return;
		}
		
		String query = getPara(QUERY_STATEMENT);
		String[] params = {Ping.UUID};
		
		BaseService service = new BaseService() {
			@Override
			public void putRefRecord(List<Record> records) {
				// TODO Auto-generated method stub	
				for (Record record : records) {
					Record store = Db.findFirst(Store.SQL_GET_STORE_NAME, 
							record.getStr(Ping.STORE));
					record.set(Ping.STORE_NAME, store.getStr(Store.NAME));
					
					Record user = Db.findFirst(User.SQL_GET_USER_SHORT_INFO, 
							record.getStr(Ping.PUBLISHER));
					record.set(Ping.PUBLISHER_NAME, user.getStr(User.NAME));
					record.set(Ping.PUBLISHER_CRATE, user.getInt(User.CRATE));
					record.set(Ping.PUBLISHER_SEX, user.getInt(User.SEX));
					record.set(Ping.PUBLISHER_CHATHEAD, user.getStr(User.CHATHEAD));
				}
			}
		};
		
		List<Record> records = service.find(query, Ping.SQL_GET_PININFO, params);
		service.putRefRecord(records);
		
		if (records == null) {
			renderOperateError();
		}else {
			renderResult(records, true);
		}
	}

	public void status(){
		if (!checkQuery()) {
			return;
		}	
		
		String query = getPara(QUERY_STATEMENT);
		String[] params = {Ping.UUID};
		
		BaseService service = new BaseService() {};
		List<Record> records = service.find(query, Ping.SQL_GET_PININFO, params);
		
		if (records == null ) {
			renderOperateError();
			return;
		}else if (records.size() == 0) {
			renderNullResult();
			return;
		}
		
		Record ping = records.get(0);
		try {
			JSONObject attr = new JSONObject(query);
			int operation = attr.getInt(OPERATION);
			Record pinger = Db.findFirst(User.SQL_GET_UUID_BY_TOKEN, attr.getString(TOKEN));
			String operator = pinger.getStr(User.UUID);
			
			switch (ping.getInt(Ping.STATUS)) {
			//0
			case Ping.STATUS_WAITING:
			{
				if(Ping.STATUS_PHONING == operation && 
						ping.getStr(Ping.PINGER) == null &&
						!ping.getStr(Ping.PUBLISHER).equals(operator)){
					ping.set(Ping.PINGER, operation);
				}else if ((Ping.STATUS_REVOCATION == operation ||
						Ping.STATUS_DELETE == operation) &&
						ping.getStr(Ping.PUBLISHER).equals(operation)) {
					ping.remove(Ping.PINGER);
				}else {
					renderPingError();
					return;
				}
				break;
			}
			//1
			case Ping.STATUS_PHONING:
			{
				if (ping.getStr(Ping.PINGER).equals(operator)) {
					if (Ping.STATUS_WAITING == operation) {
						ping.remove(Ping.PINGER);
					}else if (Ping.STATUS_PROCESSIONG == operation) {
						//拼单完成
					}else {
						renderPingError();
						return;
					}
				}else {
					renderPingError();
					return;
				}
				break;
			}
			//6
			case Ping.STATUS_PROCESSIONG:
			{
				if (ping.getStr(Ping.PUBLISHER).equals(operator)) {
					if (Ping.STATUS_WAITING == operation ||
							Ping.STATUS_PROCESSIONG == operation ||
							Ping.STATUS_DELETE == operation) {
						ping.remove(Ping.PINGER);
					}else if(Ping.STATUS_SUCCESS == operation){
						
					}else {
						renderPingError();
						return;
					}
				}else if (ping.getStr(Ping.PINGER).equals(operation)) {
					if (Ping.STATUS_PHONING == operation) {
						
					}else {
						renderPingError();
						return;
					}
				}else {
					renderPingError();
					return;
				}
				break;
			}

			default:
			{
				//3、5
				if (Ping.STATUS_REVOCATION == ping.getInt(Ping.STATUS) ||
						Ping.STATUS_TIMEOUT == ping.getInt(Ping.STATUS)) {
					if (Ping.STATUS_WAITING == operation) {
						
					}else {
						renderPingError();
						return;
					}
				}
				//2
				else if(Ping.STATUS_SUCCESS == ping.getInt(Ping.STATUS)){
					if (Ping.STATUS_REVOCATION == operation ||
							Ping.STATUS_DELETE == operation) {
						
					}else {
						renderPingError();
						return;
					}
				}
				//4
				else if(Ping.STATUS_DELETE == ping.getInt(Ping.STATUS)){
					renderPingError();
					return;
				}
				//else
				else {
					renderPingError();
					return;
				}
				break;
			}
			}
			
			ping.set(Ping.STATUS, operation);
			Db.update(Ping.TABLE_NAME, ping);
			renderSuccess();
			return;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			renderLack();
			return ;
		}
	}
}
